import { createElement, createTextNode } from './dom'
import { isFunction, isFunctionComponent } from './util'
import unMountNode from './vdom/unMountNode'
import updateNodeElement from './vdom/updateNodeElement'

export default function mountElement(vitrualDOM, container, oldEl) {
    if (isFunction(vitrualDOM)) {
        moutComponent(vitrualDOM, container, oldEl)
    } else {
        mountNativeElement(vitrualDOM, container, oldEl)
    }
}
// 将虚拟DOM转化为真实DOM
export function createDOMElement(vitrualDOM) {
    let newEl = null
    if (vitrualDOM.type === 'text') {
        newEl = createTextNode(vitrualDOM.props.textContent)
    } else {
        newEl = createElement(vitrualDOM.type)
        updateNodeElement(newEl, vitrualDOM)
    }
    vitrualDOM.children.forEach(child => {
        mountElement(child, newEl)
    })
    if (vitrualDOM.props && vitrualDOM.props.ref) {
        vitrualDOM.props.ref(newEl)
    }
    return newEl
}

function mountNativeElement(vitrualDOM, container, oldEl) {
    
    let newEl = createDOMElement(vitrualDOM)
    if (oldEl) {
        container.insertBefore(newEl,oldEl)
        unMountNode(oldEl)
    } else {
        container.appendChild(newEl)
    }
    newEl._virtualDOM = vitrualDOM
  
    let component = vitrualDOM.component
    if (component) {
        component.setDOM(newEl)
    }
    return newEl
}

function moutComponent(vitrualDOM, container, oldEl) {
    let newVirtualDOM = null
    // 函数组件
    if (isFunctionComponent(vitrualDOM)) {
        newVirtualDOM = vitrualDOM.type(vitrualDOM.props || {})
    } else {
        newVirtualDOM = buildClassCmponent(vitrualDOM)
        console.log('类组件')
    }

    mountElement(newVirtualDOM, container, oldEl)
    let component = newVirtualDOM.component
    if (component) {
        component.props && component.props.ref && component.props.ref(component)
        component.componentDidMount()
    }
}

function buildClassCmponent(vitrualDOM) {
    const component = new vitrualDOM.type(vitrualDOM.props)
    const newVirtualDOM = component.render()
    newVirtualDOM.component = component
    return newVirtualDOM
}